package com.example.criminalintent.activity;

import java.util.Date;
import java.util.UUID;

import com.example.criminalintent.R;
import com.example.criminalintent.model.Crime;
import com.example.criminalintent.model.CrimeLab;
import com.example.criminalintent.model.Photo;
import com.example.criminalintent.model.PictureUtils;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.drawable.BitmapDrawable;
import android.hardware.Camera;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.NavUtils;
import android.text.Editable;
import android.text.TextWatcher;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;

public class CrimeFragment extends Fragment {
	
	private static final String TAG = "CrimeFragment";
	public static final String EXTRA_CRIME_ID = "CrimeFragment_CrimeID";
	private static final String DIALOG_DATE = "date";
	private static final int REQUEST_DATE = 0;
	private static final int REQUEST_PHOTO = 1;

	private Crime mCrime;
	// controls
	private EditText mTitleField;
	private Button mDateButton;
	private CheckBox mSolvedCheckbox;
	private ImageButton mPhotoButton;
	private ImageView mPhotoView;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// CrimeFragment will be implementing options menu
		setHasOptionsMenu(true);

		UUID crime_id = (UUID) getArguments().getSerializable(EXTRA_CRIME_ID);
		mCrime = CrimeLab.get(getActivity()).getCrime(crime_id);
		if (mCrime == null) {
			Toast.makeText(getActivity(), "NULL", Toast.LENGTH_SHORT).show();
			mCrime = new Crime();
		}
	} 

	@TargetApi(Build.VERSION_CODES.HONEYCOMB)
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View v = inflater.inflate(R.layout.fragment_crime, container, false);

		// to enable the app icon to work as a Up button
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
				&& NavUtils.getParentActivityName(getActivity()) != null) {
			getActivity().getActionBar().setDisplayHomeAsUpEnabled(true);
		}

		//init controls
		initControls(v);
		
		// handle take photos
		mPhotoButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				Intent i = new Intent(getActivity(), CrimeCameraActivity.class);
				startActivityForResult(i, REQUEST_PHOTO);
			}
		});
		
		// Check camera presence
		// If camera is not available, disable camera functionality
		PackageManager pm = getActivity().getPackageManager();
		boolean hasCamera = pm.hasSystemFeature(PackageManager.FEATURE_CAMERA) || 
				pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT) || 
				(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD &&
				Camera.getNumberOfCameras() > 0);
		if (!hasCamera) {
			mPhotoButton.setEnabled(false);
		}
		
		// handle text displayed
		mTitleField.setText(mCrime.getTitle());
		// handle the text changed listener
		mTitleField.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence c, int start, int before, int count) {
				mCrime.setTitle(c.toString());
			}

			@Override
			public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
					int arg3) {
			}

			@Override
			public void afterTextChanged(Editable arg0) {
			}
		});

		// update date string of mDateButton
		updateDate(mCrime);

		mDateButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View arg0) {
				// change the default date by using DatePicker
				FragmentManager fm = getActivity().getSupportFragmentManager();
				DatePickerFragment dialog = DatePickerFragment.newInstance(mCrime.getDate());

				// set Target Fragment so change of Date will appear in CrimeFragment
				dialog.setTargetFragment(CrimeFragment.this, REQUEST_DATE);

				dialog.show(fm, DIALOG_DATE);
			}
		});

		// handle the checkbox
		mSolvedCheckbox.setChecked(mCrime.isSolved());
		mSolvedCheckbox.setOnCheckedChangeListener(new OnCheckedChangeListener() {
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
				// Set the crime's solved property
				mCrime.setSolved(isChecked);
			}
		});

		return v;
	}

	private void initControls(View v) {
		mTitleField = (EditText) v.findViewById(R.id.txtCrimeTitle);
		mDateButton = (Button) v.findViewById(R.id.btnCrimeDate);
		mSolvedCheckbox = (CheckBox) v.findViewById(R.id.chkCrimeSolved);
		mPhotoButton = (ImageButton) v.findViewById(R.id.crime_imageButton);
		mPhotoView = (ImageView) v.findViewById(R.id.crime_imageView);
	}

	public static CrimeFragment newInstance(UUID crimeId) {
		Bundle args = new Bundle();
		args.putSerializable(EXTRA_CRIME_ID, crimeId);

		CrimeFragment fragment = new CrimeFragment();
		fragment.setArguments(args);

		return fragment;
	}

	public void returnResult() {
		getActivity().setResult(Activity.RESULT_OK, null);
	}

	/**
	 * retrieve the extra, set the date on the Crime, and 
	 * refresh the text of the date button.
	 */
	@Override
	public void onActivityResult(int requestCode, int resultCode, Intent data) {
		if (resultCode == Activity.RESULT_OK) {
			if (requestCode == REQUEST_DATE) {
				Date newDate = (Date) data.getSerializableExtra(DatePickerFragment.EXTRA_DATE);
				mCrime.setDate(newDate);
				// update date string of mDateButton
				updateDate(mCrime);
			} else if (requestCode == REQUEST_PHOTO) {
				// Create a new Photo object and attach it to the crime
				String fileName = data.getStringExtra(CrimeCameraFragment.EXTRA_PHOTO_FILENAME);
				if (fileName != null) {
					Photo p = new Photo(fileName);
					mCrime.setPhoto(p);
					// display the captured image on ImageView
					showPhoto();
					Log.i(TAG, "Crime " + mCrime.getTitle() + " has a Photo: " + fileName);
				}
			}
		}
	}

	public void updateDate(Crime mCrime) {
		// handle the default date setting
		String dateFormat = DateFormat.format("EEE, LLL dd, yyyy", mCrime.getDate()).toString();
		// update Date
		mDateButton.setText(dateFormat);
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		switch (id) {
		// Response to the app icon (Home - Up) menu item
		case android.R.id.home:
			// first check to see if there is a parent activity of
			// CrimePagerActivity named in the metadata
			if (NavUtils.getParentActivityName(getActivity()) != null) {
				// If there is, navigate to the parent activity
				// the parent activity is CrimeListActivity
				NavUtils.navigateUpFromSameTask(getActivity());
			}
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}
	
	/**
	 * Save data to JSON file
	 */
	@Override
	public void onPause() {
		super.onPause();
		CrimeLab.get(getActivity()).saveCrimes();
	}
	
	/**
	 * Display scaled image on ImageView
	 */
	private void showPhoto() {
		// (Re)set the image button's image based on our photo
		Photo mPhoto = mCrime.getPhoto();
		BitmapDrawable bitmapDrawable = null;
		if (mPhoto != null) {
			String path = getActivity().getFileStreamPath(mPhoto.getFilename()).getAbsolutePath();
			bitmapDrawable = PictureUtils.getScaledDrawable(getActivity(), path);
		}
		mPhotoView.setImageDrawable(bitmapDrawable);
	}

	/**
	 * Have the photo ready as soon as CrimeFragment’s view becomes visible to the user.
	 */
	@Override
	public void onStart() {
		super.onStart();
		showPhoto();
	}
	
	/**
	 * Recycle the image and unload the image from ImageView
	 */
	@Override
	public void onStop() {
		super.onStop();
		PictureUtils.cleanImageView(mPhotoView);
	}
}
